package ft.app.gtig.gui.video;

import com.haulmont.cuba.core.app.DataService;
import com.haulmont.cuba.core.entity.FileDescriptor;
import com.haulmont.cuba.core.global.LoadContext;
import com.haulmont.cuba.core.global.Metadata;
import com.haulmont.cuba.gui.components.*;
import com.haulmont.cuba.gui.components.actions.BaseAction;
import com.haulmont.cuba.gui.data.DataSupplier;
import com.haulmont.cuba.gui.data.Datasource;
import com.haulmont.cuba.gui.upload.FileUploadingAPI;
import com.haulmont.cuba.gui.xml.layout.ComponentsFactory;
import com.haulmont.cuba.gui.components.AbstractEditor;
import ft.app.gtig.entity.Video;
import ft.app.gtig.service.QiNiuFileStorageService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;

public class VideoEdit extends AbstractEditor<Video> {
    private Logger log = LoggerFactory.getLogger(getClass());

    @Inject
    private FileUploadingAPI fileUploadingAPI;
    @Inject
    private QiNiuFileStorageService qiNiuFileStorageService;
    @Inject
    private DataSupplier dataSupplier;
    @Inject
    private DataService dataService;
    @Inject
    private Metadata metadata;

    @Inject
    private Datasource<Video> dsVideo;


    @Inject
    private ComponentsFactory componentsFactory;

    @Inject
    private FileMultiUploadField multiUploadField;

    @Inject
    private FlowBoxLayout videosFlowBox;

    @Inject
    private FileMultiUploadField uploadField;

    @Inject
    private FlowBoxLayout coverFlowBox;


    @Override
    public void init(Map<String, Object> params) {


        multiUploadField.setFileSizeLimit(200*1024*1024l);
        multiUploadField.addQueueUploadCompleteListener(() -> {

            StringBuilder video = new StringBuilder(333);

            for (Map.Entry<UUID, String> entry : multiUploadField.getUploadsMap().entrySet()) {
                UUID fileId = entry.getKey();
                String fileName = entry.getValue();
                FileDescriptor srcFd = fileUploadingAPI.getFileDescriptor(fileId, fileName);

                FileDescriptor dstFd = dataSupplier.commit(srcFd);
                qiNiuFileStorageService.uploadFile(fileUploadingAPI.getFile(fileId), dstFd.getId().toString());

                video.append(dstFd.getId());
                video.append(",");
            }

            if (video.length() > 0) {
                getItem().setVideo(video.toString());
                displayVideos();
            }

            showNotification("Uploaded files: " + multiUploadField.getUploadsMap().values(), NotificationType.HUMANIZED);
            multiUploadField.clearUploads();
        });

        multiUploadField.addFileUploadErrorListener(event ->
                showNotification("File upload error", NotificationType.HUMANIZED));


        uploadField.addQueueUploadCompleteListener(() -> {

            StringBuilder cover = new StringBuilder(333);

            for (Map.Entry<UUID, String> entry : uploadField.getUploadsMap().entrySet()) {
                UUID fileId = entry.getKey();
                String fileName = entry.getValue();
                FileDescriptor srcFd = fileUploadingAPI.getFileDescriptor(fileId, fileName);

                FileDescriptor dstFd = dataSupplier.commit(srcFd);
                qiNiuFileStorageService.uploadFile(fileUploadingAPI.getFile(fileId), dstFd.getId().toString());

                cover.append(dstFd.getId());
                cover.append(",");
            }

            if (cover.length() > 0) {
                getItem().setCover(cover.toString());
                displayCover();
            }

            showNotification("Uploaded files: " + uploadField.getUploadsMap().values(), NotificationType.HUMANIZED);
            uploadField.clearUploads();
        });

        uploadField.addFileUploadErrorListener(event ->
                showNotification("File upload error", NotificationType.HUMANIZED));
    }


    @Override
    protected void postInit() {
        displayVideos();
        displayCover();
    }

    private void displayVideos() {
        videosFlowBox.removeAll();
        if (getItem().getVideo() == null) {
            return;
        }

        String[] videosId = StringUtils.split(getItem().getVideo(),",");;
        if (videosId.length == 0) {
            return;
        }

        for (String videoId : videosId) {
            UUID fileId = UUID.fromString(videoId);
            FileDescriptor fd = dataService.load(LoadContext.create(FileDescriptor.class).setId(fileId));
            if (fd == null || fd.isDeleted()) {
                continue;
            }

            VBoxLayout embedded = createEmbedded(fd);
            if (embedded == null) {
                continue;
            }

            videosFlowBox.add(embedded);
        }
    }

    private VBoxLayout createEmbedded(FileDescriptor videoFile) {

        VBoxLayout vBoxLayout = componentsFactory.createComponent(VBoxLayout.class);
        vBoxLayout.setWidth(null);

        Embedded embedded = componentsFactory.createComponent(Embedded.class);

        try {

            embedded.setType(Embedded.Type.OBJECT);
            embedded.setSource(videoFile.getName(), qiNiuFileStorageService.downloadFile(videoFile));

            vBoxLayout.add(embedded);

            Button button = componentsFactory.createComponent(Button.class);
            button.setAlignment(Alignment.TOP_CENTER);
            button.setCaption("Clear");
            button.setAction(new BaseAction("hello") {
                @Override
                public void actionPerform(Component component) {
                    videosFlowBox.remove(vBoxLayout);
//                    vBoxLayout.setVisible(false);
                    VideoEdit.this.clearVideo(videoFile);
                }
            });
            vBoxLayout.add(button);

            return vBoxLayout;
        } catch (IOException e) {
            log.error("createEmbedded error.", e);
            return null;
        }
    }

    private void clearVideo(FileDescriptor videoFile) {
        StringBuilder videos = new StringBuilder(333);
        String[] srcvideos = getItem().getVideo().split(",");
        for (String video : srcvideos) {
            if (StringUtils.equals(video, videoFile.getId().toString())) {
                continue;
            }
            videos.append(video);
            videos.append(",");
        }

        getItem().setVideo(videos.toString());
    }



    private void displayCover() {
        coverFlowBox.removeAll();
        if (getItem().getCover() == null) {
            return;
        }

        String[] coversId = StringUtils.split(getItem().getCover(),",");
        if (coversId.length == 0) {
            return;
        }

        for (String coverId : coversId) {
            UUID fileId = UUID.fromString(coverId);
            FileDescriptor fd = dataService.load(LoadContext.create(FileDescriptor.class).setId(fileId));
            if (fd == null || fd.isDeleted()) {
                continue;
            }

            VBoxLayout embedded = createEmbedded2(fd);
            if (embedded == null) {
                continue;
            }

            coverFlowBox.add(embedded);
        }
    }

    private VBoxLayout createEmbedded2(FileDescriptor coverFile) {

        VBoxLayout vBoxLayout = componentsFactory.createComponent(VBoxLayout.class);
        vBoxLayout.setWidth(null);

        Embedded embedded = componentsFactory.createComponent(Embedded.class);

        try {

            embedded.setType(Embedded.Type.OBJECT);
            embedded.setSource(coverFile.getName(), qiNiuFileStorageService.downloadFile(coverFile));

            vBoxLayout.add(embedded);

            Button button = componentsFactory.createComponent(Button.class);
            button.setAlignment(Alignment.TOP_CENTER);
            button.setCaption("Clear");
            button.setAction(new BaseAction("hello") {
                @Override
                public void actionPerform(Component component) {
                    coverFlowBox.remove(vBoxLayout);
//                    vBoxLayout.setVisible(false);
                    VideoEdit.this.clearCover2(coverFile);
                }
            });
            vBoxLayout.add(button);

            return vBoxLayout;
        } catch (IOException e) {
            log.error("createEmbedded error.", e);
            return null;
        }
    }

    private void clearCover2(FileDescriptor coverFile) {
        StringBuilder covers = new StringBuilder(333);
        String[] srccover = getItem().getCover().split(",");
        for (String cover : srccover) {
            if (StringUtils.equals(cover, coverFile.getId().toString())) {
                continue;
            }
            covers.append(cover);
            covers.append(",");
        }

        getItem().setCover(covers.toString());
    }

}